package com.xiaozhen.jt809.server;

import com.xiaozhen.jt809.adapter.MyServerChannelHandlerAdapter;
import com.xiaozhen.jt809.codec.MsgPackHexDecoder;
import com.xiaozhen.jt809.codec.MsgPackHexEncoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.ByteOrder;
import java.util.concurrent.TimeUnit;

/**
 * HISTORY
 *
 * @author zhenweisheng
 * @date 2021/9/14 11:26
 * @description:
 */
@Slf4j
@Service
public class TcpServer {

    @Autowired
    private MyServerChannelHandlerAdapter myServerChannelHandlerAdapter;
    @Autowired
    private MsgPackHexEncoder msgPackHexEncoder;
    @Autowired
    private MsgPackHexDecoder msgPackHexDecoder;

    /**
     * 创建一个服务器端的程序类进行NIO的启动，同时可以设置Channel
     */
    ServerBootstrap serverBootstrap = new ServerBootstrap();
    /**
     * 创建主线程池（接收线程池）
     */
    EventLoopGroup boosGroup = new NioEventLoopGroup();
    /**
     * 创建工作线程池
     */
    EventLoopGroup workGroup = new NioEventLoopGroup();

    public void runServer() {
        try {
            //初始化group
            serverBootstrap.group(boosGroup, workGroup);
            serverBootstrap.channel(NioServerSocketChannel.class);
            //接收到的信息处理器
            //执行handler方法
            serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ChannelPipeline pipeline = ch.pipeline();
                    //读超时  写超时  读写超时 单位（秒）
                    pipeline.addLast(new IdleStateHandler(180, 180, 180, TimeUnit.SECONDS));
                    //前置编解码器
                    pipeline.addLast(msgPackHexEncoder);
                    //粘包拆包   根据长度域进行拆包
//                    pipeline.addLast(new LengthFieldBasedFrameDecoder(
//                            ByteOrder.BIG_ENDIAN, 65535,
//                            1, 4, -5, 0,
//                            true));
                    //后置编解码器
                    pipeline.addLast(msgPackHexDecoder);
                    //自定义的编解码器
                    pipeline.addLast(myServerChannelHandlerAdapter);
                }
            });
            serverBootstrap.option(ChannelOption.SO_BACKLOG, 128);
            serverBootstrap.option(ChannelOption.TCP_NODELAY, true);
            serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
            ChannelFuture channelFuture = serverBootstrap.bind(9809).sync();
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
            log.info("[出现异常] 释放资源");
            boosGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }
    }


}
